package io.dy.termination;

import io.dy.utils.ThreadUtils;

/**
 * @author : dmj
 * @date: 2024/7/4 7:04 下午
 * @description: 两阶段终止 监控线程
 */
public abstract class TwoPhaseAbstractTermination {

    /**
     * 监控线程
     */
    private Thread monitorThread;

    /**
     * 停止标识
     */
    protected volatile boolean stop;

    /**
     * 监控方法是否已经启动 保证监控线程只启动一次
     */
    protected volatile boolean starting;

    /**
     *  启动
     */
    public void start(){
        //判断如果 starting 为true 则标识已启动 直接return 需要考虑并发  加锁控制 运用dcl
        if(starting){
            return;
        }
        if (extracted()) return;

        monitorThread = new Thread(()->{
            while (!stop){
                //编写监控业务代码
                ThreadUtils.printThreadLog("监控业务执行！");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {

                }
            }

            //如果走到下面的代码 说明stop = true 标识监控线程停止 那么这个时候 需要将 starting 再次设置为false 这样的话 才能保证重新启动成功 否则将永远无法重新启动
            starting = false;
        });
        monitorThread.start();
    }

    /**
     * 停止
     */
    public void stop(){
        stop = true;
        //线程打断可以让sleep中的线程苏醒
        monitorThread.interrupt();
    }

    /**
     * 抽象加锁方式 供子类提供具体加锁方式
     * @return
     */
    public abstract boolean extracted();
}
